// 高阶组件：本质就是一个函数， 一个包装了另外一个 React 组件的 React 组件

import React from 'react'
import ReactDOM from 'react-dom'
import img from './images/cat.jpg'

// 创建高阶组件
function withMouse(WrappedComponent) {
    // 该组件提供复用的状态逻辑
    class Mouse extends React.Component {
        // 鼠标状态
        state = {
            x: 0,
            y: 0
    
        }

        handleMouseMove = e => {
            this.setState({
                x: e.clientX,
                y: e.clientY
            })
        }

        // 控制鼠标状态的逻辑
        componentDidMount() {
            window.addEventListener('mousemove', this.handleMouseMove)
        }

        componentWillUnmount() {
            window.removeEventListener('mousemove', this.handleMouseMove)
        }

        render(){
            // 解决被包装组件传入props丢失的现象
            return (<WrappedComponent {...this.state}{...this.props} />)
        }
    }

    // 设置display name
    Mouse.displayName = `WithMouse${getDisplayName(WrappedComponent)}`

    return Mouse
}

// 用户高阶组件，只返回相同的组件名，类似python装饰器中返回的函数名是一样的类似
function getDisplayName(WrappedComponent) {
    return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}

// 用来测试的高阶组件
const Position = props => (
    <p>
        鼠标单前位置：(x: {props.x}, y: {props.y})
    </p>
)

// 猫抓老鼠
const Cat = props => (
    <img 
        src={img} 
        alt="猫" 
        height="10"
        width="50"
        height="50"
        style={{
            position: "absolute",
            top: props.y -25,
            left: props.x - 25
        }} 
    />
)

// 调用高阶组件, 获取增强后的组件
const MousePosition = withMouse(Position)
const MouseCat = withMouse(Cat)

class App extends React.Component{
    render() {
        return (
            <div>
                <h1>高阶组件</h1>
                {/* 使用增强的组件 */}
                <MousePosition a="1"/>
                <MouseCat />
            </div>
        )
    }
}

ReactDOM.render(<App />, document.getElementById('root'))
